mod physics;
mod visual;
mod mover;
mod balloon;
mod spring;

use crate::mover::Mover;
use ggez::{Context, GameResult, GameError, graphics, glam::Vec2};


pub struct State{
    balloon: balloon::Balloon,
    spring: spring::Spring,
    balloon1: balloon::Balloon,
    spring1: spring::Spring,
    spring11: spring::Spring,
    balloon2: balloon::Balloon,
    spring2: spring::Spring,
    spring21: spring::Spring
}

impl State{
    pub fn new(_ctx: &mut Context) -> State {

        let location = Vec2{x: 100.0,y: 400.0};
        let balloon = balloon::Balloon::new(location);

        let anchor = Vec2{x: 400.0, y: 0.0};
        let len = 200.0;
        let spring = spring::Spring::new(anchor, len);


        let location = Vec2{x: 700.0,y: 100.0};
        let balloon1 = balloon::Balloon::new(location);

        let anchor = Vec2{x: 400.0, y: 0.0};
        let len = 200.0;
        let spring1 = spring::Spring::new(anchor, len);

        let anchor = Vec2{x: 400.0, y: 0.0};
        let len = 200.0;
        let spring11 = spring::Spring::new(anchor, len);


        let location = Vec2{x: 300.0,y: 200.0};
        let balloon2 = balloon::Balloon::new(location);

        let anchor = Vec2{x: 400.0, y: 0.0};
        let len = 200.0;
        let spring2 = spring::Spring::new(anchor, len);

        let anchor = Vec2{x: 400.0, y: 0.0};
        let len = 200.0;
        let spring21 = spring::Spring::new(anchor, len);

        State{ balloon, spring, balloon1, spring1, spring11, balloon2, spring2, spring21 }
    }
}

impl ggez::event::EventHandler<GameError> for State {
    fn update(&mut self, ctx: &mut Context) -> GameResult {
        

        let fg = Vec2 {x: 0.0, y: 0.1*self.balloon.get_mass()};
        self.balloon.apply_force(fg);
        let fg = Vec2 {x: 0.0, y: 0.1*self.balloon1.get_mass()};
        self.balloon1.apply_force(fg);
        let fg = Vec2 {x: 0.0, y: 0.1*self.balloon2.get_mass()};
        self.balloon2.apply_force(fg);
        
        self.balloon.update(ctx);
        self.balloon1.update(ctx);
        self.balloon2.update(ctx);
        self.spring.connect(&mut self.balloon);
        self.spring1.connect(&mut self.balloon1);
        self.spring11.connect(&mut self.balloon);
        self.spring2.connect(&mut self.balloon2);
        self.spring21.connect(&mut self.balloon1);

        self.spring1.set_anchor(self.balloon.get_location());
        self.spring11.set_anchor(self.balloon1.get_location());
        self.spring2.set_anchor(self.balloon1.get_location());
        self.spring21.set_anchor(self.balloon2.get_location());
        Ok(())
    }
    fn draw(&mut self, ctx: &mut Context) -> GameResult {
        let mut canvas = graphics::Canvas::from_frame(ctx, graphics::Color::WHITE);
        self.spring.display(ctx, &mut canvas);
        self.spring1.display(ctx, &mut canvas);
        self.spring2.display(ctx, &mut canvas);
        self.balloon.display(ctx, &mut canvas);
        self.balloon1.display(ctx, &mut canvas);
        self.balloon2.display(ctx, &mut canvas);
        canvas.finish(ctx)?;
        Ok(())
    }
}